// 当前正在执行的effect函数
let activeEffect
// 定义一个effect栈
let effectStack = []


// 注册副作用函数
export function effect(fn, options = {}) {
    const effectFn = () => {
        try {
            effectStack.push(effectFn)
            activeEffect = effectFn

            return fn()
        } finally {
            // pop完之后length-1
            effectStack.pop()
            activeEffect = effectStack[effectStack.length - 1]
        }
    }
    // 如果没有lazy直接执行，不需要懒操作
    if (!options.lazy) {
        effectFn()
    }
    effectFn.scheduler = options.scheduler
    return effectFn
}

// 定义桶来收集对应键和对应依赖

const targetMap = new WeakMap()

// 保存依赖
export function track(target, key) {

    if (!activeEffect) {
        return
    }
    //  先给targetMap中添加键值对
    let depsMap = targetMap.get(target)
    if (!depsMap) {
        targetMap.set(target, depsMap = new Map())
    }
    let deps = depsMap.get(key)
    if (!deps) {
        depsMap.set(key, deps = new Set())
    }
    // 把当前执行的副作用函数添加到set中
    deps.add(activeEffect)
}

// 把依赖从桶中拿出来并执行
export function trigger(target, key) {
    const depsMap = targetMap.get(target)
    if (!depsMap) {
        return
    }
    // 拿到对应键的依赖集合
    const deps = depsMap.get(key)
    if (!deps) {
        return
    }
    // 遍历依赖集合中的副作用函数并且执行
    deps.forEach((effectFn) => {
        if (effectFn.scheduler) {
            effectFn.scheduler(effectFn)
        } else {
            effectFn()
        }
    })
}
